package com.lineage.server.model;

import com.add.ItemTimeTableadd;
import com.add.L1ItemTimeadd;
import com.lineage.config.ConfigAlt;
import com.lineage.config.ConfigRate;
import com.lineage.data.event.ProtectorSet;
import com.lineage.server.IdFactory;
import com.lineage.server.clientpackets.C_LoginToServer;
import com.lineage.server.datatables.InnKeyTable;
import com.lineage.server.datatables.ItemTable;
import com.lineage.server.datatables.ItemTimeTable;
import com.lineage.server.datatables.lock.CharItemsTimeReading;
import com.lineage.server.datatables.lock.FurnitureSpawnReading;
import com.lineage.server.datatables.sql.LetterTable;
import com.lineage.server.model.Instance.L1FurnitureInstance;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.serverpackets.S_EquipmentWindow;
import com.lineage.server.serverpackets.S_ItemName;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SystemMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Item;
import com.lineage.server.world.World;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1Inventory extends L1Object {
  private static final Log _log = LogFactory.getLog(L1Inventory.class);
  
  private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  
  protected List<L1ItemInstance> _items = new CopyOnWriteArrayList<>();
  
  public int[] slot_ring = new int[4];
  
  public int[] slot_earring = new int[2];
  
  public static final int MAX_WEIGHT = 1500;
  
  public static final int OK = 0;
  
  public static final int SIZE_OVER = 1;
  
  public static final int WEIGHT_OVER = 2;
  
  public static final int AMOUNT_OVER = 3;
  
  public static final int WAREHOUSE_TYPE_PERSONAL = 0;
  
  public static final int WAREHOUSE_TYPE_CLAN = 1;
  
  private static final long serialVersionUID = 1L;
  
  public static final void recordToFiles(String filename, String info, Timestamp timestamp) {
    try {
      Throwable t = null;
      BufferedWriter out = new BufferedWriter(
          new FileWriter("./玩家纪录/" + filename + "/" + sdf.format(timestamp) + ".txt", true));
      try {
        out.write(info);
        out.newLine();
        out.flush();
      } finally {
        if (out != null)
          out.close(); 
      } 
    } catch (IOException e) {
      e.printStackTrace();
    } 
  }
  
  public void toSlotPacket(L1PcInstance pc, L1ItemInstance item) {
    int select_idx = -1;
    int idx = 0;
    if (item.getItem().getType2() == 2) {
      int i;
      switch (item.getItem().getType()) {
        case 1:
        case 2:
        case 3:
        case 4:
          idx = item.getItem().getType();
          break;
        case 5:
          idx = 6;
          break;
        case 6:
          idx = 5;
          break;
        case 7:
        case 13:
          idx = 7;
          break;
        case 8:
          idx = 10;
          break;
        case 10:
          idx = 11;
          break;
        case 14:
          idx = 22;
          break;
        case 15:
          idx = 23;
          break;
        case 16:
          idx = 24;
          break;
        case 17:
          idx = 14;
          break;
        case 18:
          idx = 25;
          break;
        case 19:
          idx = 26;
          break;
        case 20:
          idx = 27;
          break;
        case 9:
          i = 0;
          while (i < this.slot_ring.length) {
            if (this.slot_ring[i] == item.getId())
              select_idx = i; 
            i++;
          } 
          if (item.isEquipped() && select_idx == -1) {
            i = 0;
            while (i < this.slot_ring.length) {
              if (this.slot_ring[i] == 0) {
                this.slot_ring[i] = item.getId();
                idx = 18 + i;
                break;
              } 
              i++;
            } 
          } 
          if (!item.isEquipped() && select_idx != -1) {
            this.slot_ring[select_idx] = 0;
            idx = 18 + select_idx;
          } 
          break;
        case 12:
          i = 0;
          while (i < this.slot_earring.length) {
            if (this.slot_earring[i] == item.getId())
              select_idx = i; 
            i++;
          } 
          if (item.isEquipped() && select_idx == -1) {
            i = 0;
            while (i < this.slot_earring.length) {
              if (this.slot_earring[i] == 0) {
                this.slot_earring[i] = item.getId();
                idx = 12 + i;
                break;
              } 
              i++;
            } 
          } 
          if (!item.isEquipped() && select_idx != -1) {
            this.slot_earring[select_idx] = 0;
            idx = 12 + select_idx;
          } 
          break;
      } 
    } else if (item.getItem().getType2() == 1) {
      idx = 8;
    } 
    if (idx != 0)
      pc.sendPackets((ServerBasePacket)new S_EquipmentWindow(pc, item.getId(), idx, item.isEquipped())); 
  }
  
  public int getSize() {
    if (this._items.isEmpty())
      return 0; 
    return this._items.size();
  }
  
  public List<L1ItemInstance> getItems() {
    return this._items;
  }
  
  public int getWeight() {
    int weight = 0;
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      weight += item.getWeight();
    } 
    return weight;
  }
  
  public int checkAddItem(L1ItemInstance item, long count) {
    if (item == null)
      return -1; 
    if (item.getCount() <= 0L || count <= 0L)
      return -1; 
    if (getSize() > ConfigAlt.MAX_NPC_ITEM || (getSize() == ConfigAlt.MAX_NPC_ITEM && (
      !item.isStackable() || !checkItem(item.getItem().getItemId()))))
      return 1; 
    long weight = getWeight() + item.getItem().getWeight() * count / 1000L + 1L;
    if (weight < 0L || item.getItem().getWeight() * count / 1000L < 0L)
      return 2; 
    if (weight > 1500.0D * ConfigRate.RATE_WEIGHT_LIMIT_PET)
      return 2; 
    L1ItemInstance itemExist = findItemId(item.getItemId());
    if (itemExist != null && itemExist.getCount() + count > Long.MAX_VALUE)
      return 3; 
    return 0;
  }
  
  public int checkAddItemToWarehouse(L1ItemInstance item, long count, int type) {
    if (item == null)
      return -1; 
    if (item.getCount() <= 0L || count <= 0L)
      return -1; 
    int maxSize = 100;
    if (type == 0) {
      maxSize = ConfigAlt.MAX_PERSONAL_WAREHOUSE_ITEM;
    } else if (type == 1) {
      maxSize = ConfigAlt.MAX_CLAN_WAREHOUSE_ITEM;
    } 
    if (getSize() > maxSize || (getSize() == maxSize && (
      !item.isStackable() || !checkItem(item.getItem().getItemId()))))
      return 1; 
    return 0;
  }
  
  public synchronized L1ItemInstance storeItem(int itemid, long count) {
    try {
      if (count <= 0L)
        return null; 
      L1Item temp = ItemTable.get().getTemplate(itemid);
      if (temp == null)
        return null; 
      if (temp.isStackable()) {
        L1ItemInstance item = new L1ItemInstance(temp, count);
        if (findItemId(itemid) == null) {
          item.setId(IdFactory.get().nextId());
          World.get().storeObject((L1Object)item);
        } 
        return storeItem(item);
      } 
      L1ItemInstance result = null;
      int i = 0;
      while (i < count) {
        L1ItemInstance item2 = new L1ItemInstance(temp, 1L);
        item2.setId(IdFactory.get().nextId());
        World.get().storeObject((L1Object)item2);
        storeItem(item2);
        result = item2;
        i++;
      } 
      return result;
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  public synchronized L1ItemInstance storeItem(L1ItemInstance item) {
    try {
      Random random1;
      if (item == null)
        return null; 
      if (item.getCount() <= 0L)
        return null; 
      if (this._items.contains(item))
        return null; 
      int itemId = item.getItem().getItemId();
      if (item.isStackable()) {
        if (itemId == 40309) {
          L1ItemInstance[] items = findItemsId(itemId);
          L1ItemInstance[] array;
          int length = (array = items).length;
          int j = 0;
          while (j < length) {
            L1ItemInstance tgitem = array[j];
            String racegamNo = tgitem.getraceGamNo();
            if (item.getraceGamNo().equals(racegamNo)) {
              tgitem.setCount(tgitem.getCount() + item.getCount());
              updateItem(tgitem);
              return tgitem;
            } 
            j++;
          } 
        } else {
          L1ItemInstance findItem = findItemId(item.getItem().getItemId());
          if (findItem != null) {
            if (findItem.getId() == item.getId()) {
              if (this instanceof L1PcInventory) {
                L1PcInventory pc_inv = (L1PcInventory)this;
                L1PcInstance pc = pc_inv.getOwner();
                if (pc != null)
                  _log.info("增加物品时发生重复ID异常: (人物:" + pc.getName() + ", 道具:" + 
                      item.getItem().getName() + ", Objid:" + item.getId() + ")"); 
              } 
              return null;
            } 
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        } 
        if (itemId == 40312) {
          L1ItemInstance findItem = findKeyId(item.getKeyId());
          if (findItem != null) {
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        } 
        if (itemId == 82503) {
          L1ItemInstance findItem = findKeyId(item.getKeyId());
          if (findItem != null) {
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        } 
        if (itemId == 82504) {
          L1ItemInstance findItem = findKeyId(item.getKeyId());
          if (findItem != null) {
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        } 
        boolean SKIP = false;
        switch (itemId) {
          case 40309:
          case 40312:
          case 82503:
          case 82504:
            SKIP = true;
            break;
        } 
        L1ItemInstance findItem2 = findItemId(itemId);
        if (findItem2 != null && !SKIP) {
          int OneHundredMillion = 100000000;
          int Limit = 500000000;
          long TotalCount = findItem2.getCount() + item.getCount();
          if (findItem2.getItemId() == 40308 && TotalCount > 500000000L) {
            long count = TotalCount / 100000000L;
            if (this instanceof L1PcInventory) {
              int i = 0;
              while (i < count) {
                TotalCount -= 100000000L;
                i++;
              } 
              storeItem(92088, count);
              L1PcInventory pc_inv2 = (L1PcInventory)this;
              L1PcInstance pc2 = pc_inv2.getOwner();
              pc2.sendPackets((ServerBasePacket)new S_SystemMessage("身上金币超过5亿，自动转换成金条。"));
            } 
          } 
          findItem2.setCount(TotalCount);
          updateItem(findItem2);
          return findItem2;
        } 
      } 
      item.setX(getX());
      item.setY(getY());
      item.setMap(getMapId());
      int maxchargeCount = item.getItem().getMaxChargeCount();
      switch (itemId) {
        case 20383:
          maxchargeCount = 50;
          break;
        case 40006:
        case 40007:
        case 40008:
        case 40009:
        case 140006:
        case 140008:
          random1 = new Random();
          maxchargeCount -= random1.nextInt(5);
          break;
      } 
      if (item.getChargeCount() > 0) {
        item.setChargeCount(item.getChargeCount());
      } else {
        item.setChargeCount(maxchargeCount);
      } 
      if (item.getRemainingTime() > 0)
        item.setRemainingTime(item.getRemainingTime()); 
      item.setBless(item.getBless());
      if (itemId == ProtectorSet.ITEM_ID && this instanceof L1PcInventory) {
        L1PcInventory pc_inv = (L1PcInventory)this;
        L1PcInstance pc = pc_inv.getOwner();
        if (pc != null && !pc.isProtector()) {
          pc.setProtector(true);
          C_LoginToServer.checkforProtector(pc);
          World.get().broadcastPacketToAll((ServerBasePacket)new S_ServerMessage(2924));
        } 
      } 
      if (itemId == 56148 && this instanceof L1PcInventory) {
        L1PcInventory pc_inv = (L1PcInventory)this;
        L1PcInstance pc = pc_inv.getOwner();
        if (pc != null && !pc.isEffectGS() && !pc.isEffectDADIS())
          pc.setGS(true); 
      } 
      if (itemId == 56147 && this instanceof L1PcInventory) {
        L1PcInventory pc_inv = (L1PcInventory)this;
        L1PcInstance pc = pc_inv.getOwner();
        if (pc != null && !pc.isEffectGS() && !pc.isEffectDADIS())
          pc.setDADIS(true); 
      } 
      if (itemId == 44216 && this instanceof L1PcInventory) {
        L1PcInventory pc_inv = (L1PcInventory)this;
        L1PcInstance pc = pc_inv.getOwner();
        if (pc != null && !pc._isCraftsmanHeirloom() && !pc._isMarsSoul())
          pc.setCraftsmanHeirloom(true); 
      } 
      if (itemId == 44217 && this instanceof L1PcInventory) {
        L1PcInventory pc_inv = (L1PcInventory)this;
        L1PcInstance pc = pc_inv.getOwner();
        if (pc != null && !pc._isMarsSoul() && !pc._isCraftsmanHeirloom())
          pc.setMarsSoul(true); 
      } 
      if (itemId == 40312 && !InnKeyTable.checkey(item)) {
        item.setIdentified(true);
        InnKeyTable.StoreKey(item);
      } 
      if (itemId == 82503 && !InnKeyTable.checkey(item)) {
        item.setIdentified(true);
        InnKeyTable.StoreKey(item);
      } 
      if (itemId == 82504 && !InnKeyTable.checkey(item)) {
        item.setIdentified(true);
        InnKeyTable.StoreKey(item);
      } 
      if (this instanceof L1PcInventory) {
        set_time_item(item);
        set_time_itemadd(item);
      } 
      this._items.add(item);
      insertItem(item);
      return item;
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  public synchronized L1ItemInstance storeItem(L1ItemInstance item, int bless) {
    try {
      Random random1;
      if (item == null)
        return null; 
      if (item.getCount() <= 0L)
        return null; 
      if (this._items.contains(item))
        return null; 
      if (item.isStackable())
        if (item.getItem().getUseType() == -5) {
          L1ItemInstance[] items = findItemsId(item.getItemId());
          L1ItemInstance[] arrayOfL1ItemInstance1;
          int j = (arrayOfL1ItemInstance1 = items).length;
          for (int i = 0; i < j; i++) {
            L1ItemInstance tgitem = arrayOfL1ItemInstance1[i];
            String gamNo1 = tgitem.getGamNo1();
            if (item.getGamNo1().equals(gamNo1)) {
              tgitem.setCount(tgitem.getCount() + item.getCount());
              updateItem(tgitem);
              return tgitem;
            } 
          } 
        } else {
          L1ItemInstance findItem = findItemId(item.getItem().getItemId());
          if (findItem != null) {
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        }  
      item.setX(getX());
      item.setY(getY());
      item.setMap(getMapId());
      int chargeCount = item.getItem().getMaxChargeCount();
      switch (item.getItem().getItemId()) {
        case 40006:
        case 40007:
        case 40008:
        case 40009:
          random1 = new Random();
          chargeCount -= random1.nextInt(5);
          break;
      } 
      item.setChargeCount(chargeCount);
      if (item.getItem().getType2() == 0 && item.getItem().getType() == 2) {
        item.setRemainingTime(item.getItem().getLightFuel());
      } else {
        item.setRemainingTime(item.getItem().getMaxUseTime());
      } 
      item.setBless(bless);
      this._items.add(item);
      insertItem(item);
      return item;
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  private void set_time_itemadd(L1ItemInstance item) {
    L1ItemTimeadd itemTime = (L1ItemTimeadd)ItemTimeTableadd.TIME.get(Integer.valueOf(item.getItemId()));
    if (itemTime != null && itemTime != null) {
      item.set_time(itemTime.get_remain_time());
      CharItemsTimeReading.get().addTime(item.getId(), itemTime.get_remain_time());
      if (this instanceof L1PcInventory) {
        L1PcInventory pc_inv = (L1PcInventory)this;
        L1PcInstance pc = pc_inv.getOwner();
        pc.sendPackets((ServerBasePacket)new S_ItemName(item));
      } 
    } 
  }
  
  public synchronized L1ItemInstance storeTradeItem(L1ItemInstance item) {
    try {
      if (item == null)
        return null; 
      if (item.getCount() <= 0L)
        return null; 
      if (item.isStackable())
        if (item.getItem().getUseType() == -5) {
          L1ItemInstance[] items = findItemsId(item.getItemId());
          byte b;
          int i;
          L1ItemInstance[] arrayOfL1ItemInstance1;
          for (i = (arrayOfL1ItemInstance1 = items).length, b = 0; b < i; ) {
            L1ItemInstance tgitem = arrayOfL1ItemInstance1[b];
            int gamNo = tgitem.getGamNo();
            if (item.getGamNo() == gamNo) {
              tgitem.setCount(tgitem.getCount() + item.getCount());
              updateItem(tgitem);
              return tgitem;
            } 
            b++;
          } 
        } else {
          L1ItemInstance findItem = findItemId(item.getItem().getItemId());
          if (findItem != null) {
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        }  
      item.setX(getX());
      item.setY(getY());
      item.setMap(getMapId());
      this._items.add(item);
      insertItem(item);
      return item;
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  public synchronized L1ItemInstance storeTradeItemOld(L1ItemInstance item) {
    try {
      if (item == null)
        return null; 
      if (item.getCount() <= 0L)
        return null; 
      int itemId = item.getItem().getItemId();
      if (item.isStackable()) {
        if (itemId == 40309) {
          L1ItemInstance[] items = findItemsId(itemId);
          L1ItemInstance[] array;
          int length = (array = items).length;
          int j = 0;
          while (j < length) {
            L1ItemInstance tgitem = array[j];
            String racegamNo = tgitem.getraceGamNo();
            if (item.getraceGamNo().equals(racegamNo)) {
              tgitem.setCount(tgitem.getCount() + item.getCount());
              updateItem(tgitem);
              return tgitem;
            } 
            j++;
          } 
        } else {
          L1ItemInstance findItem = findItemId(item.getItem().getItemId());
          if (findItem != null) {
            if (findItem.getId() == item.getId()) {
              if (this instanceof L1PcInventory) {
                L1PcInventory pc_inv = (L1PcInventory)this;
                L1PcInstance pc = pc_inv.getOwner();
                if (pc != null)
                  _log.info("增加物品时发生重复ID异常2: (人物:" + pc.getName() + ", 道具:" + 
                      item.getItem().getName() + ", Objid:" + item.getId() + ")"); 
              } 
              return null;
            } 
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        } 
        if (itemId == 40312) {
          L1ItemInstance findItem = findKeyId(item.getKeyId());
          if (findItem != null) {
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        } 
        if (itemId == 82503) {
          L1ItemInstance findItem = findKeyId(item.getKeyId());
          if (findItem != null) {
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        } 
        if (itemId == 82504) {
          L1ItemInstance findItem = findKeyId(item.getKeyId());
          if (findItem != null) {
            findItem.setCount(findItem.getCount() + item.getCount());
            updateItem(findItem);
            return findItem;
          } 
        } 
        boolean SKIP = false;
        switch (itemId) {
          case 40309:
          case 40312:
          case 82503:
          case 82504:
            SKIP = true;
            break;
        } 
        L1ItemInstance findItem2 = findItemId(itemId);
        if (findItem2 != null && !SKIP) {
          int OneHundredMillion = 100000000;
          int Limit = 1000000000;
          long TotalCount = findItem2.getCount() + item.getCount();
          if (findItem2.getItemId() == 40308 && TotalCount > 1000000000L) {
            long count = TotalCount / 100000000L;
            if (this instanceof L1PcInventory) {
              int i = 0;
              while (i < count) {
                TotalCount -= 100000000L;
                i++;
              } 
              storeItem(92088, count);
              L1PcInventory pc_inv2 = (L1PcInventory)this;
              L1PcInstance pc2 = pc_inv2.getOwner();
              pc2.sendPackets((ServerBasePacket)new S_SystemMessage("身上金币超过十亿，自动转换成金条。"));
            } 
          } 
          findItem2.setCount(TotalCount);
          updateItem(findItem2);
          return findItem2;
        } 
      } 
      item.setX(getX());
      item.setY(getY());
      item.setMap(getMapId());
      if (itemId == ProtectorSet.ITEM_ID && this instanceof L1PcInventory) {
        L1PcInventory pc_inv3 = (L1PcInventory)this;
        L1PcInstance pc3 = pc_inv3.getOwner();
        if (pc3 != null && !pc3.isProtector()) {
          pc3.setProtector(true);
          World.get().broadcastPacketToAll((ServerBasePacket)new S_ServerMessage(2924));
        } 
      } 
      if (itemId == 56148 && this instanceof L1PcInventory) {
        L1PcInventory pc_inv3 = (L1PcInventory)this;
        L1PcInstance pc3 = pc_inv3.getOwner();
        if (pc3 != null && !pc3.isEffectGS() && !pc3.isEffectDADIS())
          pc3.setGS(true); 
      } 
      if (itemId == 56147 && this instanceof L1PcInventory) {
        L1PcInventory pc_inv3 = (L1PcInventory)this;
        L1PcInstance pc3 = pc_inv3.getOwner();
        if (pc3 != null && !pc3.isEffectGS() && !pc3.isEffectDADIS())
          pc3.setDADIS(true); 
      } 
      if (itemId == 56146 && this instanceof L1PcInventory) {
        L1PcInventory pc_inv3 = (L1PcInventory)this;
        L1PcInstance pc3 = pc_inv3.getOwner();
        if (pc3 != null && !pc3._isCraftsmanHeirloom() && !pc3._isMarsSoul())
          pc3.setCraftsmanHeirloom(true); 
      } 
      if (itemId == 56145 && this instanceof L1PcInventory) {
        L1PcInventory pc_inv3 = (L1PcInventory)this;
        L1PcInstance pc3 = pc_inv3.getOwner();
        if (pc3 != null && !pc3._isMarsSoul() && !pc3._isCraftsmanHeirloom())
          pc3.setMarsSoul(true); 
      } 
      if (itemId == 40312 && !InnKeyTable.checkey(item))
        InnKeyTable.StoreKey(item); 
      if (itemId == 82503 && !InnKeyTable.checkey(item))
        InnKeyTable.StoreKey(item); 
      if (itemId == 82504 && !InnKeyTable.checkey(item))
        InnKeyTable.StoreKey(item); 
      if (this instanceof L1PcInventory) {
        set_time_item(item);
        set_time_itemadd(item);
      } 
      this._items.add(item);
      insertItem(item);
      return item;
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  public boolean consumeItem(int itemid, long count) {
    if (count <= 0L)
      return false; 
    if (ItemTable.get().getTemplate(itemid).isStackable()) {
      L1ItemInstance item = findItemId(itemid);
      if (item != null && item.getCount() >= count) {
        removeItem(item, count);
        return true;
      } 
    } else {
      L1ItemInstance[] itemList = findItemsId(itemid);
      if (itemList.length == count) {
        int i = 0;
        while (i < count) {
          removeItem(itemList[i], 1L);
          i++;
        } 
        return true;
      } 
      if (itemList.length > count) {
        DataComparator dc = new DataComparator();
        Arrays.sort(itemList, dc);
        int j = 0;
        while (j < count) {
          removeItem(itemList[j], 1L);
          j++;
        } 
        return true;
      } 
    } 
    return false;
  }
  
  public long removeItem(int objectId, long count) {
    L1ItemInstance item = getItem(objectId);
    return removeItem(item, count);
  }
  
  public void removeItem(int itemid) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getItemId() == itemid)
        removeItem(item); 
    } 
  }
  
  public long removeItem(L1ItemInstance item) {
    return removeItem(item, item.getCount());
  }
  
  public long removeItem(L1ItemInstance item, long count) {
    if (item == null)
      return 0L; 
    if (item.getCount() <= 0L || count <= 0L)
      return 0L; 
    if (item.getCount() < count)
      count = item.getCount(); 
    if (item.getCount() == count) {
      int itemId = item.getItem().getItemId();
      if (itemId >= 49016 && itemId <= 49025) {
        LetterTable lettertable = new LetterTable();
        lettertable.deleteLetter(item.getId());
      } else if (itemId >= 41383 && itemId <= 41400) {
        Iterator<L1Object> iterator = World.get().getObject().iterator();
        while (iterator.hasNext()) {
          L1Object l1object = iterator.next();
          if (l1object instanceof L1FurnitureInstance) {
            L1FurnitureInstance furniture = (L1FurnitureInstance)l1object;
            if (furniture.getItemObjId() != item.getId())
              continue; 
            FurnitureSpawnReading.get().deleteFurniture(furniture);
          } 
        } 
      } 
      deleteItem(item);
      World.get().removeObject((L1Object)item);
    } else {
      item.setCount(item.getCount() - count);
      updateItem(item);
    } 
    return count;
  }
  
  public void deleteItem(L1ItemInstance item) {
    int itemid = item.getItemId();
    if (itemid == 40312)
      InnKeyTable.DeleteKey(item); 
    if (itemid == 82503)
      InnKeyTable.DeleteKey(item); 
    if (itemid == 82504)
      InnKeyTable.DeleteKey(item); 
    this._items.remove(item);
  }
  
  
//	public void deleteItem(final L1ItemInstance item) {
//		this._items.remove(item);
//	}
  
  public synchronized L1ItemInstance tradeItem(int objectId, long count, L1Inventory inventory) {
    L1ItemInstance item = getItem(objectId);
    return tradeItem(item, count, inventory);
  }
  
  public synchronized L1ItemInstance tradeItem(L1ItemInstance item, int count, int showId, L1GroundInventory inventory) {
    L1ItemInstance carryItem;
    if (item == null)
      return null; 
    if (item.getCount() <= 0L || count <= 0)
      return null; 
    if (item.isEquipped())
      return null; 
    if (item.getCount() < count)
      return null; 
    if (item.getCount() == count) {
      deleteItem(item);
      carryItem = item;
      carryItem.set_showId(showId);
    } else {
      item.setCount(item.getCount() - count);
      updateItem(item);
      carryItem = ItemTable.get().createItem(item.getItem().getItemId());
      carryItem.set_showId(showId);
      carryItem.setCount(count);
      carryItem.setEnchantLevel(item.getEnchantLevel());
      carryItem.setIdentified(item.isIdentified());
      carryItem.set_durability(item.get_durability());
      carryItem.setChargeCount(item.getChargeCount());
      carryItem.setRemainingTime(item.getRemainingTime());
      carryItem.setLastUsed(item.getLastUsed());
      carryItem.setBless(item.getBless());
      if (carryItem.getItem().getItemId() == 40312 || carryItem.getItem().getItemId() == 82503 || 
        carryItem.getItem().getItemId() == 82504) {
        carryItem.setInnNpcId(item.getInnNpcId());
        carryItem.setKeyId(item.getKeyId());
        carryItem.setHall(item.checkRoomOrHall());
        carryItem.setDueTime(item.getDueTime());
      } 
    } 
    return inventory.storeTradeItem(carryItem);
  }
  
  public synchronized L1ItemInstance tradeItem(L1ItemInstance item, long count, L1Inventory inventory) {
    L1ItemInstance carryItem;
    if (item == null)
      return null; 
    if (item.getCount() <= 0L || count <= 0L)
      return null; 
    if (item.isEquipped())
      return null; 
    if (item.getCount() < count)
      return null; 
    if (item.getCount() == count) {
      deleteItem(item);
      carryItem = item;
    } else {
      item.setCount(item.getCount() - count);
      updateItem(item);
      carryItem = ItemTable.get().createItem(item.getItem().getItemId());
      carryItem.setCount(count);
      carryItem.setEnchantLevel(item.getEnchantLevel());
      carryItem.setIdentified(item.isIdentified());
      carryItem.set_durability(item.get_durability());
      carryItem.setChargeCount(item.getChargeCount());
      carryItem.setRemainingTime(item.getRemainingTime());
      carryItem.setLastUsed(item.getLastUsed());
      carryItem.setBless(item.getBless());
      if (carryItem.getItem().getItemId() == 40312 || carryItem.getItem().getItemId() == 82503 || 
        carryItem.getItem().getItemId() == 82504) {
        carryItem.setInnNpcId(item.getInnNpcId());
        carryItem.setKeyId(item.getKeyId());
        carryItem.setHall(item.checkRoomOrHall());
        carryItem.setDueTime(item.getDueTime());
      } 
    } 
    return inventory.storeTradeItem(carryItem);
  }
  
  public L1ItemInstance receiveDamage(int objectId) {
    L1ItemInstance item = getItem(objectId);
    return receiveDamage(item);
  }
  
  public L1ItemInstance receiveDamage(L1ItemInstance item) {
    return receiveDamage(item, 1);
  }
  
  public L1ItemInstance receiveDamage(L1ItemInstance item, int count) {
    if (item == null)
      return null; 
    int itemType = item.getItem().getType2();
    int currentDurability = item.get_durability();
    if ((currentDurability == 0 && itemType == 0) || currentDurability < 0) {
      item.set_durability(0);
      return null;
    } 
    if (itemType == 0) {
      int minDurability = (item.getEnchantLevel() + 5) * -1;
      int durability = currentDurability - count;
      if (durability < minDurability)
        durability = minDurability; 
      if (currentDurability > durability)
        item.set_durability(durability); 
    } else {
      int maxDurability = item.getEnchantLevel() + 5;
      int durability = currentDurability + count;
      if (durability > maxDurability)
        durability = maxDurability; 
      if (currentDurability < durability)
        item.set_durability(durability); 
    } 
    updateItem(item, 1);
    return item;
  }
  
  public L1ItemInstance recoveryDamage(L1ItemInstance item) {
    if (item == null)
      return null; 
    int itemType = item.getItem().getType2();
    int durability = item.get_durability();
    if ((durability == 0 && itemType != 0) || durability < 0) {
      item.set_durability(0);
      return null;
    } 
    if (itemType == 0) {
      item.set_durability(durability + 1);
    } else {
      item.set_durability(durability - 1);
    } 
    updateItem(item, 1);
    return item;
  }
  
  public L1ItemInstance findItemIdNoEq(int itemId) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getItem().getItemId() == itemId && !item.isEquipped())
        return item; 
    } 
    return null;
  }
  
  public L1ItemInstance findItemIdEq(int itemId) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getItem().getItemId() == itemId && item.isEquipped())
        return item; 
    } 
    return null;
  }
  
  public L1ItemInstance findItemId(int itemId) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getItem().getItemId() == itemId)
        return item; 
    } 
    return null;
  }
  
  public L1ItemInstance findItemId(String nameid) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getName().equals(nameid))
        return item; 
    } 
    return null;
  }
  
  public L1ItemInstance findKeyId(int keyid) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getKeyId() == keyid)
        return item; 
    } 
    return null;
  }
  
  public L1ItemInstance[] findItemsId(int itemId) {
    ArrayList<L1ItemInstance> itemList = new ArrayList<>();
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getItemId() == itemId && !item.isEquipped() && item.get_time() == null && !item.isEquipped())
        itemList.add(item); 
    } 
    return itemList.<L1ItemInstance>toArray(new L1ItemInstance[0]);
  }
  
  public L1ItemInstance[] findItemsIdNotEquipped(int itemId) {
    ArrayList<L1ItemInstance> itemList = new ArrayList<>();
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getItemId() == itemId && !item.isEquipped())
        itemList.add(item); 
    } 
    return itemList.<L1ItemInstance>toArray(new L1ItemInstance[0]);
  }
  
  public L1ItemInstance[] findItemsIdNoEqWithEnchant(int itemId, int enchant) {
    ArrayList<L1ItemInstance> itemList = new ArrayList<>();
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getItemId() == itemId && item.getEnchantLevel() == enchant && !item.isEquipped())
        itemList.add(item); 
    } 
    return itemList.<L1ItemInstance>toArray(new L1ItemInstance[0]);
  }
  
  public L1ItemInstance[] findItemsIdNotEquipped(String nameid) {
    ArrayList<L1ItemInstance> itemList = new ArrayList<>();
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      if (item.getName().equals(nameid) && !item.isEquipped())
        itemList.add(item); 
    } 
    return itemList.<L1ItemInstance>toArray(new L1ItemInstance[0]);
  }
  
  public L1ItemInstance getItem(int objectId) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      Object itemObject = iterator.next();
      L1ItemInstance item = (L1ItemInstance)itemObject;
      if (item.getId() == objectId)
        return item; 
    } 
    return null;
  }
  
  public boolean checkItem(int itemid) {
    return checkItem(itemid, 1L);
  }
  
  public boolean checkItem(int itemId, long count) {
    if (count <= 0L)
      return true; 
    if (ItemTable.get().getTemplate(itemId).isStackable()) {
      L1ItemInstance item = findItemId(itemId);
      if (item != null && item.getCount() >= count)
        return true; 
    } else {
      L1ItemInstance[] arrayOfL1ItemInstance = findItemsId(itemId);
      if (arrayOfL1ItemInstance.length >= count)
        return true; 
    } 
    return false;
  }
  
  public boolean checkItem(L1ItemInstance item, long count) {
    return !(count > 0L && item.getCount() < count);
  }
  
  public L1ItemInstance checkItemX(int itemid, long count) {
    if (count <= 0L)
      return null; 
    if (ItemTable.get().getTemplate(itemid) != null) {
      L1ItemInstance item = findItemIdNoEq(itemid);
      if (item != null && item.getCount() >= count)
        return item; 
    } 
    return null;
  }
  
  public L1ItemInstance checkItemX2(int itemid, long count) {
    if (count <= 0L)
      return null; 
    if (ItemTable.get().getTemplate(itemid) != null) {
      L1ItemInstance item = findItemIdEq(itemid);
      if (item != null && item.getCount() >= count)
        return item; 
    } 
    return null;
  }
  
  public boolean checkEnchantItem(int itemid, int enchant, long count) {
    if (ItemTable.get().getTemplate(itemid).isStackable()) {
      L1ItemInstance item = findItemIdNoEq(itemid);
      if (item != null && item.getEnchantLevel() == enchant && item.getCount() >= count)
        return true; 
    } else {
      int num = 0;
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item2 = iterator.next();
        if (item2.isEquipped())
          continue; 
        if (item2.getItemId() == itemid && item2.getEnchantLevel() == enchant && ++num == count)
          return true; 
      } 
    } 
    return false;
  }
  
  public boolean consumeEnchantItem(int itemid, int enchant, long count) {
    if (ItemTable.get().getTemplate(itemid).isStackable()) {
      L1ItemInstance item = findItemIdNoEq(itemid);
      if (item != null && item.getEnchantLevel() == enchant && item.getCount() >= count) {
        removeItem(item, count);
        return true;
      } 
    } else {
      L1ItemInstance[] itemList = findItemsIdNoEqWithEnchant(itemid, enchant);
      if (itemList.length == count) {
        int i = 0;
        while (i < count) {
          removeItem(itemList[i], 1L);
          i++;
        } 
        return true;
      } 
      if (itemList.length > count) {
        DataComparator dc = new DataComparator();
        Arrays.sort(itemList, dc);
        int j = 0;
        while (j < count) {
          removeItem(itemList[j], 1L);
          j++;
        } 
        return true;
      } 
    } 
    return false;
  }
  
  public boolean checkItemNotEquipped(String nameid, long count) {
    return !(count != 0L && count > countItems(nameid));
  }
  
  public boolean checkItemNotEquipped(int itemid, long count) {
    return !(count != 0L && count > countItems(itemid));
  }
  
  public boolean checkItem(int[] ids) {
    int len = ids.length;
    int[] counts = new int[len];
    int i = 0;
    while (i < len) {
      counts[i] = 1;
      i++;
    } 
    return checkItem(ids, counts);
  }
  
  public boolean checkItem(int[] ids, int[] counts) {
    int i = 0;
    while (i < ids.length) {
      if (!checkItem(ids[i], counts[i]))
        return false; 
      i++;
    } 
    return true;
  }
  
  public long countItems(int itemId) {
    if (!ItemTable.get().getTemplate(itemId).isStackable()) {
      L1ItemInstance[] arrayOfL1ItemInstance = findItemsIdNotEquipped(itemId);
      return arrayOfL1ItemInstance.length;
    } 
    L1ItemInstance item = findItemId(itemId);
    if (item != null)
      return item.getCount(); 
    return 0L;
  }
  
  public long countItems(String nameid) {
    if (!ItemTable.get().getTemplate(nameid).isStackable()) {
      L1ItemInstance[] arrayOfL1ItemInstance = findItemsIdNotEquipped(nameid);
      return arrayOfL1ItemInstance.length;
    } 
    L1ItemInstance item = findItemId(nameid);
    if (item != null)
      return item.getCount(); 
    return 0L;
  }
  
  public void shuffle() {
    Collections.shuffle(this._items);
  }
  
  public void clearItems() {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      Object itemObject = iterator.next();
      L1ItemInstance item = (L1ItemInstance)itemObject;
      World.get().removeObject((L1Object)item);
    } 
  }
  
  public void loadItems() {}
  
  public void insertItem(L1ItemInstance item) {}
  
  public void updateItem(L1ItemInstance item) {}
  
  public void onRemoveItem(L1ItemInstance item) {
    this._items.remove(item);
  }
  
  public void updateItem(L1ItemInstance item, int colmn) {}
  
  private void set_time_item(L1ItemInstance item) {
    if (item.get_time() == null) {
      int[] date = null;
      if (ItemTimeTable.TIME.get(Integer.valueOf(item.getItemId())) != null)
        date = (int[])ItemTimeTable.TIME.get(Integer.valueOf(item.getItemId())); 
      if (date != null) {
        Calendar cal = Calendar.getInstance();
        if (date[0] != 0)
          cal.add(5, date[0]); 
        if (date[1] != 0)
          cal.add(11, date[1]); 
        if (date[2] != 0)
          cal.add(12, date[2]); 
        Timestamp ts = new Timestamp(cal.getTimeInMillis());
        item.set_time(ts);
        CharItemsTimeReading.get().addTime(item.getId(), ts);
      } 
    } 
  }
  
  public class DataComparator implements Comparator<Object> {
    public int compare(Object item1, Object item2) {
      return ((L1ItemInstance)item1).getEnchantLevel() - ((L1ItemInstance)item2).getEnchantLevel();
    }
  }
}
